/**
  ************************************* Copyright ******************************
  * FileName   : ble.c
  * Version    : v1.0
  * Author     : yychao
  * Date       : 2023-06-15
  * Description:
  * Function List:
  	1. ....
  	   <version>:
  <modify staff>:
  		  <data>:
   <description>:
  	2. ...
  ******************************************************************************
 */
#include <rtthread.h>
#include "ble.h"
#include "gpio.h"
#include "usart.h"
#include "stddef.h"
#include "string.h"
#include "log.h"
struct cmd_para cmd_para_ble;
extern struct rt_semaphore static_sem0;
void ble_deal(usart_cache* recv)
{
//	usart_trans(USART1, &recv->data[1], recv->len - 1);
    char *str1 = NULL;
    char *str2 = NULL;
    char *str3 = NULL;
    str1 = (char*)&recv->data[3];
    for (uint8_t i = 0; i < cmd_para_ble.arg_num; i++) {
        str2 = strstr(str1, &cmd_para_ble.key_char[i][0]);
        if (str2 != NULL) {
            rt_sem_release(&static_sem0);
            cmd_para_ble.arg_num = 0;
        }
    }
}
uint8_t ble_cmd_check(char *cmd, uint32_t ms, uint8_t arg_num, ...) {
    uint8_t ret = 0;
#define BUFF_TX_LEN (128)
    uint8_t buff_tx[BUFF_TX_LEN] = { 0 };
    /******************************************/
    /* 1.va_list */
    va_list var_arg;
    int array[arg_num];
    /* 2.var_arg */
    va_start(var_arg, arg_num);
    for (uint8_t i = 0; i < arg_num; i++) {
        /* 3.va_arg */
        array[i] = va_arg(var_arg, int);
    }
    /******************************************/
    cmd_para_ble.arg_num = arg_num;
    memset(&cmd_para_ble.key_char[0][0], 0x00,
           sizeof(cmd_para_ble.key_char[CHAR_NUM][CHAR_LEN]));
    for (uint8_t i = 0; (i < arg_num) && (arg_num <= CHAR_NUM); i++) {
        memcpy(&cmd_para_ble.key_char[i][0], (char*) array[i], CHAR_LEN);
    }
    memset(buff_tx, 0x00, BUFF_TX_LEN);
    memcpy((char*) buff_tx, cmd, strlen(cmd));
    usart_trans(UART5, buff_tx, strlen((char*) buff_tx));
    if(0 == rt_sem_take(&static_sem0, ms))
    {
//        LOG_DEBUG("rt_sem_take static_sem0 Finished!\r\n");
        ret = 0;
    } else {
        if(arg_num == 0) {
            ret = 0;
        } else {
//            LOG_DEBUG("rt_sem_take static_sem0 Failed!\r\n");
            ret = 1;
        }
    }
    /******************************************/
    /* 4.va_end */
    va_end(var_arg);
    /******************************************/
    return ret;
}


uint8_t ble_reset(void)
{
    gpio_on(GPIOD, GPIO_PIN_0);
    rt_thread_delay(200);
    gpio_off(GPIOD, GPIO_PIN_0);
    rt_thread_delay(200);
    gpio_on(GPIOD, GPIO_PIN_0);
    rt_thread_delay(200);
}

uint8_t ble_lowpower(sw_state sta)
{
    switch(sta) {
    case OFF:
        gpio_on(GPIOD, GPIO_PIN_4);
        rt_thread_delay(200);
        gpio_off(GPIOD, GPIO_PIN_4);
        rt_thread_delay(200);
        break;
    case ON:
        gpio_off(GPIOD, GPIO_PIN_4);
        rt_thread_delay(200);
        gpio_on(GPIOD, GPIO_PIN_4);
        rt_thread_delay(200);
        break;
    }
}
uint8_t ble_at_mode(sw_state sta)
{
    switch(sta) {
    case OFF:
        gpio_off(GPIOD, GPIO_PIN_5);
        rt_thread_delay(200);
        gpio_on(GPIOD, GPIO_PIN_5);
        rt_thread_delay(200);
        break;
    case ON:
        gpio_on(GPIOD, GPIO_PIN_5);
        rt_thread_delay(200);
        gpio_off(GPIOD, GPIO_PIN_5);
        rt_thread_delay(200);
        break;
    }
}
uint8_t ble_peripheral_initial(void)
{
    /*Reset PIN*/
    gpio_init_out(GPIOD, GPIO_PIN_0);
    gpio_on(GPIOD, GPIO_PIN_0);
    /*Data PIN*/
    gpio_init_in(GPIOD, GPIO_PIN_3);
    /*Wakeup PIN*/
    gpio_init_out(GPIOD, GPIO_PIN_4);
    gpio_on(GPIOD, GPIO_PIN_4);
    /*Mode PIN*/
    gpio_init_out(GPIOD, GPIO_PIN_5);
    gpio_off(GPIOD, GPIO_PIN_5);
}

uint8_t ble_module_initial(void)
{
    ble_peripheral_initial();
    ble_reset();
    LOG_DEBUG("ble reset!\r\n");
    ble_lowpower(OFF);
    LOG_DEBUG("Leave LowPower mode\r\n");
    ble_at_mode(OFF);
    LOG_DEBUG("Enter AT-CMD mode\r\n");
    ble_cmd_check("AT+NAME?", 2000, 1, "+OK");
    ble_cmd_check("AT+BAUD?", 2000, 1, "+OK");

}

